﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
using Engine;

namespace Engine
{
    class InputManager
    {
        MouseState currentMouseState;
        MouseState oldMouseState;
        KeyboardState currentKeyboredState;
        KeyboardState oldKeyboredState;
        Vector2 lastMousePressPos;

        Camara mainCamera;
        
        KeyboardState oldState;

        List<Keys> KeyBuffer = new List<Keys>();
        List<Keys> InputKeys = new List<Keys>();

        Keys[][] Combos = {new Keys[]{Keys.Right, Keys.Right},
                           new Keys[]{Keys.Left, Keys.Right, Keys.S},
                           new Keys[]{Keys.Down, Keys.Right, Keys.A},
                           new Keys[]{Keys.Left, Keys.Down, Keys.Right, Keys.A}};

        int CLEAR_TIME = 500;
        int timeSinceLastKeyPressed;

        public string lastPressedCombo = "";
        public int lastComboNO = 0;
        bool possibleCombo = false;
        bool comboHappened = false;

        public InputManager()
        {
            InputKeys.Add(Keys.Left);
            InputKeys.Add(Keys.Right);
            InputKeys.Add(Keys.Up);
            InputKeys.Add(Keys.Down);
            InputKeys.Add(Keys.A);
            InputKeys.Add(Keys.S);
        }

        public InputManager(List<Keys> inputKeys, Keys[][] combos)
        {
            this.InputKeys = inputKeys;
            this.Combos = combos;
        }

        public String getBuffer()
        {
            String temp = "";
            foreach (Keys key in KeyBuffer)
            {
                temp += " " + key;
            }
            return temp;
        }
        public void clearBuffer()
        {
            KeyBuffer.Clear();
        }

        public void update(int d_time)
        {
            oldMouseState = currentMouseState;
            oldKeyboredState = currentKeyboredState;
            currentMouseState = Mouse.GetState();
            currentKeyboredState = Keyboard.GetState();
            
            oldState = Keyboard.GetState();
            mainCamera = new Camara();
            

            if (isNewMouseClick())
            {
                lastMousePressPos = new Vector2(currentMouseState.X, currentMouseState.Y);
            }
            timeSinceLastKeyPressed += d_time;
            if (timeSinceLastKeyPressed >= CLEAR_TIME)
            {
                clearBuffer();
            }

            foreach (Keys key in InputKeys)
            {
                if (isNewKeyPress(key))
                {
                    KeyBuffer.Add(key);
                    timeSinceLastKeyPressed = 0;
                    getPressedCombo(key);
                }
            }

        }

        public int getPressedCombo(Keys _key)
        {
            int comboNO = 0;
            foreach (Keys[] combo in Combos)
            {
                int i = 0;
                int coincidenceCount = 0;
                foreach (Keys key in KeyBuffer)
                {
                    if (key == combo[i])
                    {
                        coincidenceCount++;
                        possibleCombo = true;
                        i++;
                    }
                    else
                    {
                        possibleCombo = false;
                        break;
                    }
                }
                if (possibleCombo)
                {
                    if (coincidenceCount == combo.Length)
                    {
                        comboHappened = true;
                    }
                    else
                    {
                        comboHappened = false;
                    }
                    break;
                }
                comboNO++;
            }
            if (comboHappened)
            {
                clearBuffer();
                lastPressedCombo = comboNO.ToString();
                return comboNO;
            }
            if (!possibleCombo)
            {
                clearBuffer();
            }
            return -1;
        }

        public Vector2 getMouseDrag()
        {
            return new Vector2(currentMouseState.X, currentMouseState.Y) - lastMousePressPos;
        }
        public Vector2 getMousePos()
        {
            return new Vector2(currentMouseState.X, currentMouseState.Y);
        }
        public bool isNewMouseClick()
        {
            return currentMouseState.LeftButton == ButtonState.Pressed && oldMouseState.LeftButton == ButtonState.Released;
        }
        public bool isNewMouseRelease()
        {
            return currentMouseState.LeftButton == ButtonState.Released && oldMouseState.LeftButton == ButtonState.Pressed;
        }
        public bool isMouseDown()
        {
            return currentMouseState.LeftButton == ButtonState.Pressed;
        }
        public bool isNewKeyPress(Keys key)
        {
            return currentKeyboredState.IsKeyDown(key) && oldKeyboredState.IsKeyUp(key);
        }
        public bool isNewKeyRelease(Keys key)
        {
            return currentKeyboredState.IsKeyUp(key) && oldKeyboredState.IsKeyDown(key);
        }
        public bool isKeyPressed(Keys key)
        {
            return currentKeyboredState.IsKeyDown(key);
        }

        public void UpdateInput()
        {
            KeyboardState newState = Keyboard.GetState();

            // rots
            if (newState.IsKeyDown(Keys.Right))
            {
                mainCamera.rotate(new Vector3(0, -0.03f, 0));
            }
            if (newState.IsKeyDown(Keys.Left))
            {
                mainCamera.rotate(new Vector3(0, 0.03f, 0));
            }
            if (newState.IsKeyDown(Keys.Up))
            {
                mainCamera.rotate(new Vector3(-0.03f, 0, 0));
            }
            if (newState.IsKeyDown(Keys.Down))
            {
                mainCamera.rotate(new Vector3(0.03f, 0, 0));
            }
            // move
            if (newState.IsKeyDown(Keys.W))
            {
                mainCamera.Position += mainCamera.Direction * 1.5f;
            }
            if (newState.IsKeyDown(Keys.S))
            {
                mainCamera.Position -= mainCamera.Direction * 1.5f;
            }
            if (newState.IsKeyDown(Keys.A))
            {
                mainCamera.Position -= mainCamera.Left * 1.5f;
            }
            if (newState.IsKeyDown(Keys.D))
            {
                mainCamera.Position += mainCamera.Left * 1.5f;
            }
            // Otherwise, check to see whether it was down before.
            // (and therefore just released)
            else if (oldState.IsKeyDown(Keys.Space))
            {
                // Key has just been released.
            }

            oldState = newState;
        }
    }
}

